<script setup>
import { FolderOpenOutlined, CopyOutlined, DeleteOutlined, RedoOutlined, FileOutlined, InfoCircleOutlined } from "@ant-design/icons-vue";
import { ref } from 'vue';
</script>
<template>
    <!-- Modern Background -->
    <div class="app-background">
        <div class="gradient-overlay"></div>
        <div class="pattern-overlay"></div>
    </div>

    <!-- Folder Selection Modal -->
    <a-modal
        v-model:open="open"
        :closable="closable"
        :maskClosable="false"
        :keyboard="false"
        :footer="null"
        :width="modalWidth"
        @ok="(e) => { console.log(e) }"
        class="modern-modal">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title">
                    <FolderOpenOutlined class="modal-icon" />
                    选择要分析的文件夹
                </h3>
                <p class="modal-subtitle">输入文件夹路径开始磁盘空间分析</p>
            </div>

            <a-input
                id="targetFolder"
                :bordered="false"
                placeholder="请输入目标文件夹路径..."
                size="large"
                v-model:value="value"
                @change="getRecommendFolders"
                @pressEnter="startScanFolder"
                @keydown.tab.prevent="selectNextRecommedFolder($event.target.value)"
                class="modern-input" />

            <div v-if="suggestions.length > 0" class="suggestions-container">
                <div class="suggestions-header">
                    <InfoCircleOutlined />
                    <span>推荐路径</span>
                </div>
                <div v-for="(suggestion, index) in suggestions" :key="index" class="suggestion-item">
                    <FolderOpenOutlined class="suggestion-icon" />
                    <span class="suggestion-text">{{ suggestion }}</span>
                </div>
            </div>
        </div>
    </a-modal>

    <!-- Main Chart Container -->
    <div id="main" class="chart-container">
    </div>

    <!-- Enhanced Selected Item Display -->
    <div v-if="selectedFolderName.length > 0" class="selected-item-panel">
        <div class="selected-item-card">
            <div class="selected-item-header">
                <div class="selected-item-icon">
                    <FolderOpenOutlined v-if="selectedItemType === 'folder'" />
                    <FileOutlined v-else />
                </div>
                <div class="selected-item-info">
                    <h4 class="selected-item-title">已选择项目</h4>
                    <p class="selected-item-type">{{ selectedItemType === 'folder' ? '文件夹' : '文件' }}</p>
                </div>
            </div>

            <div class="selected-item-content">
                <div v-for="(name, index) in selectedFolderName" :key="index" class="selected-tag-wrapper">
                    <a-tag
                        color="blue"
                        class="selected-tag">
                        <template #icon>
                            <FolderOpenOutlined />
                        </template>
                        {{ name }}
                    </a-tag>
                </div>

                <div v-if="selectedItemSize" class="selected-item-size">
                    <span class="size-label">大小:</span>
                    <span class="size-value">{{ selectedItemSize }}</span>
                </div>
            </div>
        </div>
    </div>
    <!-- Reorganized Control Panels -->
    <!-- Performance Panel - Top Left -->
    <div v-if="!open && performanceStats && performanceStats.nodes_processed > 0" class="performance-panel-container">
        <div class="performance-panel">
            <div class="panel-header">
                <div class="panel-title">
                    <div class="performance-icon">⚡</div>
                    <span>性能监控</span>
                </div>
                <a-tag
                    v-if="isScanning"
                    color="processing"
                    class="status-tag">
                    <template #icon>
                        <div class="scanning-dot"></div>
                    </template>
                    扫描中
                </a-tag>
                <a-tag
                    v-else
                    color="success"
                    class="status-tag">
                    完成
                </a-tag>
            </div>

            <!-- Enhanced Progress Bar -->
            <div v-if="performanceStats.estimated_total_nodes > 0" class="progress-section">
                <div class="progress-info">
                    <span class="progress-label">扫描进度</span>
                    <span class="progress-percent">{{ Math.round(performanceStats.progress_percent) }}%</span>
                </div>
                <a-progress
                    :percent="Math.round(performanceStats.progress_percent)"
                    :stroke-color="isScanning ? 'linear-gradient(90deg, #1890ff, #36cfc9)' : 'linear-gradient(90deg, #52c41a, #73d13d)'"
                    :trail-color="'rgba(255,255,255,0.1)'"
                    stroke-width="8"
                    class="modern-progress" />
            </div>

            <!-- Enhanced Key Metrics -->
            <div class="metrics-grid">
                <div class="metric-card">
                    <div class="metric-icon speed-icon">🚀</div>
                    <div class="metric-content">
                        <div class="metric-label">处理速度</div>
                        <div class="metric-value speed-value">{{ formatSpeed(performanceStats.nodes_per_second) }}</div>
                    </div>
                </div>
                <div class="metric-card">
                    <div class="metric-icon eta-icon">⏱️</div>
                    <div class="metric-content">
                        <div class="metric-label">预计剩余</div>
                        <div class="metric-value eta-value">{{ formatETA(performanceStats.eta_seconds) }}</div>
                    </div>
                </div>
                <div class="metric-card">
                    <div class="metric-icon processed-icon">📊</div>
                    <div class="metric-content">
                        <div class="metric-label">已处理</div>
                        <div class="metric-value">{{ performanceStats.nodes_processed.toLocaleString() }}</div>
                    </div>
                </div>
                <div class="metric-card">
                    <div class="metric-icon data-icon">💾</div>
                    <div class="metric-content">
                        <div class="metric-label">数据量</div>
                        <div class="metric-value">{{ formatFileSize(performanceStats.bytes_processed) }}</div>
                    </div>
                </div>
            </div>

            <!-- Enhanced Detailed Stats -->
            <a-collapse v-if="!isScanning" size="small" class="details-collapse" ghost>
                <a-collapse-panel key="details" header="详细统计" class="details-panel">
                    <div class="details-grid">
                        <div class="detail-item">
                            <span class="detail-label">文件数:</span>
                            <span class="detail-value">{{ performanceStats.files_processed.toLocaleString() }}</span>
                        </div>
                        <div class="detail-item">
                            <span class="detail-label">目录数:</span>
                            <span class="detail-value">{{ performanceStats.dirs_processed.toLocaleString() }}</span>
                        </div>
                        <div class="detail-item">
                            <span class="detail-label">耗时:</span>
                            <span class="detail-value">{{ formatDuration(performanceStats.elapsed_seconds) }}</span>
                        </div>
                        <div class="detail-item">
                            <span class="detail-label">传输率:</span>
                            <span class="detail-value">{{ formatFileSize(performanceStats.bytes_per_second) }}/s</span>
                        </div>
                    </div>
                </a-collapse-panel>
            </a-collapse>
        </div>
    </div>

    <!-- Depth Panel - Top Right -->
    <div v-if="!open" class="depth-panel-container">
        <div class="depth-panel">
            <div class="panel-header">
                <div class="panel-title">
                    <div class="depth-icon">🔍</div>
                    <span>显示深度</span>
                </div>
            </div>

            <div class="depth-content">
                <div class="depth-slider-section">
                    <div class="depth-info">
                        <span class="depth-label">层级深度</span>
                        <span class="depth-value">{{ maxDepth }} 层</span>
                    </div>
                    <a-slider
                        v-model:value="maxDepth"
                        :min="1"
                        :max="5"
                        :step="1"
                        @change="refreshWithNewDepth"
                        class="modern-slider" />
                </div>

                <div v-if="lazyLoadConfig" class="lazy-load-info">
                    <div class="info-divider"></div>
                    <div class="config-items">
                        <div class="config-item">
                            <span class="config-label">最大子项:</span>
                            <span class="config-value">{{ lazyLoadConfig.max_children_per_level }}</span>
                        </div>
                        <div class="config-item">
                            <span class="config-label">最小大小:</span>
                            <span class="config-value">{{ formatFileSize(lazyLoadConfig.min_size_threshold) }}</span>
                        </div>
                        <div class="expand-hint">
                            💡 点击文件夹可展开查看更多内容
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- Action Control Panel - Bottom Left -->
    <div v-if="!open" class="action-panel-container">
        <div class="action-panel">
            <div class="panel-header">
                <div class="panel-title">
                    <div class="action-icon">⚙️</div>
                    <span>操作控制</span>
                </div>
            </div>

            <div class="action-buttons-grid">
                <!-- Copy Button -->
                <a-tooltip placement="top" title="复制选中路径到剪贴板">
                    <a-button
                        type="primary"
                        @click="copy"
                        class="grid-action-button copy-button"
                        :disabled="selectedFolder === ''">
                        <CopyOutlined class="grid-action-icon" />
                        <span class="grid-action-text">复制路径</span>
                    </a-button>
                </a-tooltip>

                <!-- Delete Button -->
                <a-tooltip placement="top" title="删除选中的文件或文件夹">
                    <a-popconfirm
                        title="确定要删除这个文件或文件夹吗？"
                        ok-text="确定"
                        cancel-text="取消"
                        @confirm="deleteByPath"
                        placement="top">
                        <a-button
                            danger
                            class="grid-action-button delete-button"
                            :disabled="selectedFolder === ''">
                            <DeleteOutlined class="grid-action-icon" />
                            <span class="grid-action-text">删除</span>
                        </a-button>
                    </a-popconfirm>
                </a-tooltip>

                <!-- Rescan Button -->
                <a-tooltip placement="top" title="重新扫描当前文件夹">
                    <a-button
                        type="primary"
                        @click="startScanFolder"
                        :loading="isScanning"
                        class="grid-action-button rescan-button">
                        <RedoOutlined v-if="!isScanning" class="grid-action-icon" />
                        <span class="grid-action-text">重新扫描</span>
                    </a-button>
                </a-tooltip>

                <!-- New Folder Button -->
                <a-tooltip placement="top" title="选择新的文件夹进行分析">
                    <a-button
                        type="primary"
                        @click="clear"
                        class="grid-action-button folder-button">
                        <FolderOpenOutlined class="grid-action-icon" />
                        <span class="grid-action-text">新建分析</span>
                    </a-button>
                </a-tooltip>
            </div>
        </div>
    </div>
</template>

<script>
import { invoke } from "@tauri-apps/api/tauri";
import { message } from "ant-design-vue";
import { TreemapChart } from 'echarts/charts';
import { TitleComponent, TooltipComponent } from 'echarts/components';
import * as echarts from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import { ref, onMounted, onUnmounted } from "vue";

const open = ref(true);
const closable = ref(false);
const modalWidth = ref('80%');
const value = ref('');
const interval = ref(null);
const os = ref('');
const suggestions = ref([]);
const selectedFolder = ref('');
const selectedFolderName = ref([]);
const selectedRecommendFolderIndex = ref(0);
const ws = ref(null);
const expandedNodes = ref(new Set()); // Track expanded nodes for lazy loading
const maxDepth = ref(5); // Default depth for initial load
const loadingNodes = ref(new Set()); // Track nodes currently being loaded
const lazyLoadConfig = ref(null); // Store lazy load configuration
const performanceStats = ref(null); // Store performance statistics
const isScanning = ref(false); // Track scanning status
const selectedItemType = ref('folder'); // Track selected item type
const selectedItemSize = ref(''); // Track selected item size

echarts.use([TitleComponent, TooltipComponent, TreemapChart, CanvasRenderer]);

// Define methods as functions
const selectNextRecommedFolder = () => {
    if (suggestions.value.length > 0) {
        value.value = suggestions.value[selectedRecommendFolderIndex.value];
        selectedRecommendFolderIndex.value = (selectedRecommendFolderIndex.value + 1) % suggestions.value.length;
    }
};

const getRecommendFolders = async () => {
    selectedRecommendFolderIndex.value = 0;
    await invoke('get_recommend_folders', { currentPath: value.value }).then((recommendFolders) => {
        suggestions.value = recommendFolders;
    }).catch((err) => {
        suggestions.value = [];
    });
};

const resizeMainDom = () => {
    let mainDiv = document.getElementById('main');

    const windowWidth = window.innerWidth;
    const windowHeight = window.innerHeight;

    mainDiv.style.width = windowWidth * 0.8 + 'px';
    mainDiv.style.height = windowHeight * 0.8 + 'px';

    console.log("Width in pixels: " + mainDiv.offsetWidth);
    console.log("Height in pixels: " + mainDiv.offsetHeight);
};

const loadTreeData = async () => {
    return await invoke('get_folder_info_with_depth', { maxDepth: maxDepth.value });
};



const refreshWithNewDepth = async () => {
    // Reset expanded nodes when depth changes
    expandedNodes.value.clear();

    // Update chart with new depth
    let chartDom = echarts.getInstanceByDom(document.getElementById('main'));
    if (chartDom) {
        let option = chartDom.getOption();
        // Safety check: ensure series exists and has at least one element
        if (!option.series || !option.series[0]) {
            console.warn('Chart series not properly initialized, skipping refresh');
            return;
        }
        option.series[0].data = await loadTreeData();
        chartDom.setOption(option);
    }
};

const mergeNodeChildren = (treeData, targetPath, newChildren) => {
    // Recursively find and update the target node
    function updateNode(nodes) {
        for (let node of nodes) {
            if (node.path === targetPath) {
                node.children = newChildren;
                node.children_loaded = true;
                return true;
            }
            if (node.children && node.children.length > 0) {
                if (updateNode(node.children)) {
                    return true;
                }
            }
        }
        return false;
    }

    updateNode(treeData);
    return treeData;
};

const expandNode = async (nodePath, chart) => {
    // Prevent multiple simultaneous loads of the same node
    if (loadingNodes.value.has(nodePath)) {
        return;
    }

    try {
        loadingNodes.value.add(nodePath);

        // Show loading indicator
        message.loading(`Loading children for ${nodePath.split('/').pop()}...`, 0.5);

        // Load children for the specific node
        const children = await invoke('get_children_by_path', {
            path: nodePath,
            maxDepth: 1 // Load one level at a time
        });

        // Mark this node as expanded
        expandedNodes.value.add(nodePath);

        // Update the tree data by merging new children
        const currentData = await loadTreeData();
        const updatedData = mergeNodeChildren(currentData, nodePath, children);

        // Update chart
        let option = chart.getOption();
        // Safety check: ensure series exists and has at least one element
        if (!option.series || !option.series[0]) {
            console.warn('Chart series not properly initialized, skipping node expansion update');
            return;
        }
        option.series[0].data = updatedData;
        chart.setOption(option);

        message.success(`Loaded ${children.length} items`, 1);

    } catch (error) {
        console.error('Failed to expand node:', error);
        message.error(`Failed to load children: ${error}`);
    } finally {
        loadingNodes.value.delete(nodePath);
    }
};

const formatFileSize = (byte) => {
    let baseUnit = 1024.0;

    if (os.value === 'Windows') {
        baseUnit = 1024.0;
    } else if (
        os.value === 'MacOS' ||
        os.value === 'Linux'
    ) {
        baseUnit = 1000.0;
    }

    if (byte < baseUnit) {
        return `${byte} B`;
    }

    const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    let size = byte;
    let reducedSize = size;
    let unitIdx = 0;

    while (size >= baseUnit && unitIdx < units.length - 1) {
        reducedSize = size;
        size /= baseUnit;
        unitIdx++;
    }

    if (size < 1.0 && unitIdx > 0) {
        unitIdx--;
        size = reducedSize;
    }

    return `${size.toFixed(2)} ${units[unitIdx]}`;
};

const formatSpeed = (nodesPerSec) => {
    if (nodesPerSec >= 1000) {
        return `${(nodesPerSec / 1000).toFixed(1)}K/s`;
    }
    return `${Math.round(nodesPerSec)}/s`;
};

const formatETA = (seconds) => {
    if (seconds === 0 || !isFinite(seconds)) return 'N/A';
    if (seconds < 60) return `${Math.round(seconds)}s`;
    if (seconds < 3600) return `${Math.round(seconds / 60)}m`;
    return `${Math.round(seconds / 3600)}h`;
};

const formatDuration = (seconds) => {
    if (seconds < 60) return `${seconds}s`;
    if (seconds < 3600) return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    return `${hours}h ${minutes}m`;
};

const renderDisk = async () => {
    await invoke('get_current_os', {}).then((value) => {
        os.value = value;
    });
    let chartDom = document.getElementById('main');
    chartDom.hidden = false;
    let myChart = echarts.init(chartDom);
    let option;
    let basePath = value.value;
    let separator = os.value === 'Windows' ? '\\' : '/';
    if (basePath[basePath.length - 1] !== separator) {
        basePath += separator;
    }

    myChart.showLoading();
    myChart.hideLoading();

    function getLevelOption() {
        return [
            {
                itemStyle: {
                    borderColor: 'rgba(255,255,255,0.3)',
                    borderWidth: 2,
                    gapWidth: 1
                },
                upperLabel: {
                    show: true,
                    color: '#fff',
                },
            },
            {
                colorSaturation: [0.35, 0.5],
                itemStyle: {
                    borderWidth: 2,
                    gapWidth: 1,
                    borderColorSaturation: 0.5
                },
                upperLabel: {
                    show: true,
                    color: '#fff',
                },
            },
            {
                colorSaturation: [0.35, 0.5],
                itemStyle: {
                    borderWidth: 2,
                    gapWidth: 1,
                    borderColorSaturation: 0.4
                },
                upperLabel: {
                    show: true,
                    color: '#fff',
                },
            },
            {
                colorSaturation: [0.35, 0.5],
                itemStyle: {
                    borderWidth: 2,
                    gapWidth: 1,
                    borderColorSaturation: 0.3
                },
                upperLabel: {
                    show: true,
                    color: '#fff',
                },
            },
            {
                colorSaturation: [0.35, 0.5],
                itemStyle: {
                    borderWidth: 2,
                    gapWidth: 1,
                    borderColorSaturation: 0.2
                },
                upperLabel: {
                    show: true,
                    color: '#fff',
                },
            },
            {
                colorSaturation: [0.35, 0.5],
                itemStyle: {
                    borderWidth: 2,
                    gapWidth: 1,
                    borderColorSaturation: 0.1
                },
                upperLabel: {
                    show: true,
                    color: '#fff',
                },
            },
        ];
    }

    myChart.setOption(
        (option = {
            title: {
                text: 'Disk Usage',
                left: 'center'
            },
            tooltip: {
                formatter: function (info) {
                    let value = info.value;
                    let treePathInfo = info.treePathInfo;
                    let treePath = [];
                    for (let i = 1; i < treePathInfo.length; i++) {
                        treePath.push(treePathInfo[i].name);
                    }
                    let relativePath = echarts.format.encodeHTML(treePath.join(separator));
                    return [
                        '<div class="tooltip-title">' +
                        (relativePath === '' ? basePath.substring(0, basePath.length - 1) : basePath + relativePath) +
                        '</div>',
                        'Disk Usage: ' + formatFileSize(value),
                    ].join('');
                }
            },
            series: [
                {
                    name: value.value,
                    type: 'treemap',
                    visibleMin: 300,
                    label: {
                        show: true,
                        formatter: function (params) {
                            return params.data.name + ' (' + formatFileSize(params.data.value) + ')';
                        }
                    },
                    upperLabel: {
                        show: true,
                        height: 30
                    },
                    itemStyle: {
                        borderColor: 'rgba(255,255,255,0.2)',
                        borderWidth: 1
                    },
                    breadcrumb: {
                        show: false
                    },
                    levels: getLevelOption(),
                    data: await loadTreeData(),
                    roam: false,
                }
            ]
        })
    );
    myChart.on('click', async function (params) {
        selectedFolder.value = ''
        for (let i = 0; i < params.treePathInfo.length; i++) {
            let name = params.treePathInfo[i].name;
            // end with separator
            if (name[name.length - 1] === separator) {
                selectedFolder.value += name;
            } else {
                selectedFolder.value += name + separator;
            }
            selectedFolderName.value = name.split(separator).filter((item) => item !== '');
        }
        selectedFolderName.value = [selectedFolderName.value[selectedFolderName.value.length - 1]]
        selectedFolder.value = selectedFolder.value.substring(0, selectedFolder.value.length - 1);

        // Set selected item type and size
        selectedItemType.value = params.data.is_dir ? 'folder' : 'file';
        selectedItemSize.value = formatFileSize(params.data.value);

        // Handle lazy loading for directories
        if (params.data.is_dir && params.data.has_children && !params.data.children_loaded) {
            await expandNode(params.data.path, myChart);
        }
    });
};

export default {
    data() {
        return {
            open,
            closable,
            modalWidth,
            value,
            interval,
            os,
            suggestions,
            selectedFolder,
            selectedFolderName,
            selectedRecommendFolderIndex,
            ws,
            expandedNodes,
            maxDepth,
            loadingNodes,
            lazyLoadConfig,
            performanceStats,
            isScanning,
            selectedItemType,
            selectedItemSize
        }
    },
    methods: {
        selectNextRecommedFolder,
        getRecommendFolders,
        resizeMainDom,
        loadTreeData,
        refreshWithNewDepth,
        mergeNodeChildren,
        expandNode,
        formatFileSize,
        formatSpeed,
        formatETA,
        formatDuration,
        renderDisk,
        async updateDisk(showBreadcrumb = false) {
            let chartDom = echarts.getInstanceByDom(document.getElementById('main'));
            if (!chartDom) return;

            let option = chartDom.getOption();
            // Safety check: ensure series exists and has at least one element
            if (!option.series || !option.series[0]) {
                console.warn('Chart series not properly initialized, skipping update');
                return;
            }

            option.series[0].data = await this.loadTreeData();
            if (showBreadcrumb) {
                option.series[0].breadcrumb.show = true;
            }
            chartDom.setOption(option);
        },
        connectWebSocket() {
            ws.value = new WebSocket("ws://localhost:3030");
            ws.value.onopen = () => {
                console.log('WebSocket connected');
            };
            ws.value.onmessage = (event) => {
                const data = JSON.parse(event.data);
                console.log('WebSocket message:', data);

                // Update performance stats and scanning status
                if (data.data) {
                    const wasScanning = isScanning.value;
                    isScanning.value = data.data.is_scanning || false;

                    if (data.data.performance) {
                        performanceStats.value = data.data.performance;
                        console.log('Performance stats:', data.data.performance);
                    }
                }

                // Handle different message types
                if (data.type === 'scan_complete') {
                    console.log('Scan completed, updating disk view with final data:', data.data);
                    isScanning.value = false;
                    this.updateDisk(true); // Show breadcrumb on completion
                } else if (data.type === 'scan_progress') {
                    // Only update during scanning, ignore progress messages after completion
                    if (isScanning.value) {
                        // Log progress data for debugging
                        if (data.data) {
                            console.log('Progress - Nodes:', data.data.total_nodes, 'Size:', data.data.total_size, 'Files:', data.data.file_count);
                            if (data.data.performance) {
                                console.log('Speed:', data.data.performance.nodes_per_second, 'nodes/sec');
                            }
                        }
                        // Update immediately on each progress message
                        this.updateDisk(false);
                    } else {
                        console.log('Ignoring progress message - scan already completed');
                    }
                }
            };
            ws.value.onerror = (event) => {
                console.error('WebSocket error:', event);
            };
            ws.value.onclose = () => {
                console.log('WebSocket closed, reconnecting...');
                setTimeout(() => this.connectWebSocket(), 1000);
            };
        },
        async startScanFolder() {
            this.resizeMainDom();

            // Reset performance stats for new scan
            performanceStats.value = null;
            isScanning.value = true;

            // Load configuration
            try {
                lazyLoadConfig.value = await invoke('get_lazy_load_config', {});
                console.log('Lazy load config:', lazyLoadConfig.value);
            } catch (error) {
                console.warn('Failed to load lazy load config:', error);
            }

            await invoke('start_scan_folder', { path: value.value });
            open.value = false;
            await this.renderDisk();

            // No polling needed - rely entirely on WebSocket updates
            console.log('Scan started, waiting for WebSocket updates...');
        },



        async clear() {
          await invoke('stop_scan_folder_and_clear', {}).then(
              () => {
                open.value = true;
                value.value = '';
                suggestions.value = [];
                clearInterval(interval.value);
                let chartDom = echarts.getInstanceByDom(document.getElementById('main'));
                if (chartDom) {
                  chartDom.clear();
                }
                selectedFolder.value = '';
                selectedFolderName.value = [];
                // Reset lazy loading state and performance stats
                expandedNodes.value.clear();
                loadingNodes.value.clear();
                maxDepth.value = 5;
                lazyLoadConfig.value = null;
                performanceStats.value = null;
                isScanning.value = false;
              }
          )
          document.getElementById('targetFolder').focus();
        },
        copy() {
            if (selectedFolder.value === '') {
                message.error('Please select a folder');
                return;
            }
            navigator.clipboard.writeText(selectedFolder.value).then(() => {
                message.success(selectedFolder.value + ' copied to clipboard');
            }, () => {
                message.error('Failed to copy ' + selectedFolder.value + ' to clipboard');
            });
        },
        deleteByPath() {
            if (selectedFolder.value === '') {
                message.error('Please select a folder');
                return;
            }
            invoke('delete_path', { path: selectedFolder.value }).then(() => {
                message.success(selectedFolder.value + ' deleted');
            }, () => {
                message.error('Failed to delete ' + selectedFolder.value);
            });
        },


    },
    mounted() {
        document.getElementById('targetFolder').focus();
        this.connectWebSocket();
    },
    beforeUnmount() {
        if (ws.value) {
            ws.value.close();
        }
    },
}
</script>

<style scoped>
/* Modern Background */
.app-background {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.gradient-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(45deg,
        rgba(102, 126, 234, 0.1) 0%,
        rgba(118, 75, 162, 0.1) 25%,
        rgba(255, 154, 158, 0.1) 50%,
        rgba(250, 208, 196, 0.1) 75%,
        rgba(212, 252, 121, 0.1) 100%);
    animation: gradientShift 15s ease infinite;
}

.pattern-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image:
        radial-gradient(circle at 25% 25%, rgba(255,255,255,0.1) 2px, transparent 2px),
        radial-gradient(circle at 75% 75%, rgba(255,255,255,0.05) 1px, transparent 1px);
    background-size: 50px 50px, 30px 30px;
    animation: patternMove 20s linear infinite;
}

@keyframes gradientShift {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.8; }
}

@keyframes patternMove {
    0% { transform: translate(0, 0); }
    100% { transform: translate(50px, 50px); }
}

/* Modern Modal Styles */
.modern-modal :deep(.ant-modal-content) {
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(20px);
    border-radius: 20px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}

.modal-content {
    padding: 20px;
}

.modal-header {
    text-align: center;
    margin-bottom: 30px;
}

.modal-title {
    font-size: 24px;
    font-weight: 600;
    color: #1a1a1a;
    margin: 0 0 8px 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
}

.modal-icon {
    font-size: 28px;
    color: #1890ff;
}

.modal-subtitle {
    color: #666;
    margin: 0;
    font-size: 14px;
}

.modern-input {
    border-radius: 12px !important;
    padding: 16px 20px !important;
    font-size: 16px !important;
    background: rgba(255, 255, 255, 0.8) !important;
    border: 2px solid rgba(24, 144, 255, 0.2) !important;
    transition: all 0.3s ease !important;
}

.modern-input:focus {
    border-color: #1890ff !important;
    box-shadow: 0 0 0 4px rgba(24, 144, 255, 0.1) !important;
    background: rgba(255, 255, 255, 0.95) !important;
}

.suggestions-container {
    margin-top: 20px;
    background: rgba(255, 255, 255, 0.6);
    border-radius: 12px;
    padding: 16px;
    backdrop-filter: blur(10px);
}

.suggestions-header {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    color: #1890ff;
    margin-bottom: 12px;
    font-size: 14px;
}

.suggestion-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    border-radius: 8px;
    transition: all 0.2s ease;
    cursor: pointer;
}

.suggestion-item:hover {
    background: rgba(24, 144, 255, 0.1);
}

.suggestion-icon {
    color: #1890ff;
    font-size: 16px;
}

.suggestion-text {
    color: #666;
    font-size: 13px;
}

/* Chart Container - Minimized border design */
.chart-container {
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    overflow: hidden;
    transition: all 0.3s ease;
}

.chart-container:hover {
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
    background: rgba(255, 255, 255, 0.15);
}

/* Selected Item Panel - Repositioned to center bottom */
.selected-item-panel {
    position: absolute;
    left: 50%;
    bottom: 20px;
    width: 320px;
    transform: translateX(-50%);
    z-index: 100;
}

.selected-item-card {
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(15px);
    border-radius: 12px;
    padding: 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.15);
    animation: slideInRight 0.3s ease;
}

@keyframes slideInRight {
    from {
        transform: translateX(100%);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

.selected-item-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
}

.selected-item-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: linear-gradient(135deg, #1890ff, #36cfc9);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 18px;
}

.selected-item-info {
    flex: 1;
}

.selected-item-title {
    font-size: 16px;
    font-weight: 600;
    color: #1a1a1a;
    margin: 0 0 4px 0;
}

.selected-item-type {
    font-size: 12px;
    color: #666;
    margin: 0;
}

.selected-item-content {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.selected-tag-wrapper {
    margin-bottom: 8px;
}

.selected-tag {
    border-radius: 8px !important;
    padding: 4px 12px !important;
    font-weight: 500 !important;
    border: none !important;
    background: linear-gradient(135deg, #1890ff, #36cfc9) !important;
}

.selected-item-size {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    background: rgba(24, 144, 255, 0.1);
    border-radius: 8px;
    margin-top: 12px;
}

.size-label {
    font-size: 12px;
    color: #666;
    font-weight: 500;
}

.size-value {
    font-size: 14px;
    color: #1890ff;
    font-weight: 600;
}

/* Reorganized Control Panels */
.performance-panel-container {
    position: absolute;
    left: 20px;
    top: 20px;
    width: 320px;
    z-index: 100;
}

.depth-panel-container {
    position: absolute;
    right: 20px;
    top: 20px;
    width: 280px;
    z-index: 100;
}

.performance-panel,
.depth-panel {
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(15px);
    border-radius: 12px;
    padding: 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.15);
    transition: all 0.3s ease;
}

.performance-panel:hover,
.depth-panel:hover {
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
    transform: translateY(-1px);
    background: rgba(255, 255, 255, 0.95);
}

.panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
}

.panel-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
    font-weight: 600;
    color: #1a1a1a;
}

.performance-icon,
.depth-icon {
    font-size: 20px;
}

.status-tag {
    border-radius: 12px !important;
    font-weight: 500 !important;
}

.scanning-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #1890ff;
    animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

/* Progress Section */
.progress-section {
    margin-bottom: 16px;
}

.progress-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}

.progress-label {
    font-size: 12px;
    color: #666;
    font-weight: 500;
}

.progress-percent {
    font-size: 14px;
    color: #1890ff;
    font-weight: 600;
}

.modern-progress :deep(.ant-progress-bg) {
    border-radius: 4px !important;
}

/* Metrics Grid */
.metrics-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-bottom: 16px;
}

.metric-card {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px;
    background: rgba(255, 255, 255, 0.6);
    border-radius: 10px;
    transition: all 0.2s ease;
}

.metric-card:hover {
    background: rgba(255, 255, 255, 0.8);
    transform: translateY(-1px);
}

.metric-icon {
    font-size: 16px;
    width: 24px;
    text-align: center;
}

.metric-content {
    flex: 1;
}

.metric-label {
    font-size: 10px;
    color: #666;
    margin-bottom: 2px;
}

.metric-value {
    font-size: 12px;
    font-weight: 600;
    color: #1a1a1a;
}

.speed-value {
    color: #1890ff;
}

.eta-value {
    color: #fa8c16;
}

/* Details Collapse */
.details-collapse :deep(.ant-collapse-header) {
    padding: 8px 0 !important;
    font-size: 12px !important;
    color: #666 !important;
}

.details-collapse :deep(.ant-collapse-content-box) {
    padding: 8px 0 !important;
}

.details-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.detail-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 11px;
}

.detail-label {
    color: #666;
}

.detail-value {
    font-weight: 500;
    color: #1a1a1a;
}

/* Depth Panel */
.depth-content {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.depth-slider-section {
    margin-bottom: 16px;
}

.depth-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}

.depth-label {
    font-size: 12px;
    color: #666;
    font-weight: 500;
}

.depth-value {
    font-size: 12px;
    color: #1890ff;
    font-weight: 600;
}

.modern-slider :deep(.ant-slider-rail) {
    background: rgba(0, 0, 0, 0.1) !important;
    border-radius: 4px !important;
}

.modern-slider :deep(.ant-slider-track) {
    background: linear-gradient(90deg, #1890ff, #36cfc9) !important;
    border-radius: 4px !important;
}

.modern-slider :deep(.ant-slider-handle) {
    border: 2px solid #1890ff !important;
    background: white !important;
    box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3) !important;
}

.lazy-load-info {
    margin-top: 16px;
}

.info-divider {
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.1), transparent);
    margin-bottom: 12px;
}

.config-items {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.config-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 11px;
}

.config-label {
    color: #666;
}

.config-value {
    font-weight: 500;
    color: #1a1a1a;
}

.expand-hint {
    font-size: 10px;
    color: #999;
    font-style: italic;
    margin-top: 8px;
    padding: 6px 8px;
    background: rgba(24, 144, 255, 0.05);
    border-radius: 6px;
    border-left: 3px solid #1890ff;
}

/* Action Panel - Bottom Left */
.action-panel-container {
    position: absolute;
    left: 20px;
    bottom: 20px;
    width: 320px;
    z-index: 100;
}

.action-panel {
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(15px);
    border-radius: 12px;
    padding: 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.15);
    transition: all 0.3s ease;
}

.action-panel:hover {
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
    transform: translateY(-1px);
    background: rgba(255, 255, 255, 0.95);
}

.action-buttons-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.grid-action-button {
    height: 48px !important;
    width: 100% !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 4px !important;
    border-radius: 10px !important;
    border: none !important;
    transition: all 0.3s ease !important;
    padding: 8px 12px !important;
}

.grid-action-button:hover {
    transform: translateY(-2px) !important;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15) !important;
}

.grid-action-button:active {
    transform: translateY(0) !important;
}

.grid-action-button:disabled {
    opacity: 0.5 !important;
    cursor: not-allowed !important;
    transform: none !important;
    width: 100% !important;
}

.grid-action-button:disabled:hover {
    opacity: 0.5 !important;
    transform: none !important;
    box-shadow: none !important;
}

.copy-button {
    background: linear-gradient(135deg, #1890ff, #36cfc9) !important;
    color: white !important;
}

.delete-button {
    background: linear-gradient(135deg, #ff4d4f, #ff7875) !important;
    color: white !important;
}

.rescan-button {
    background: linear-gradient(135deg, #52c41a, #73d13d) !important;
    color: white !important;
}

.folder-button {
    background: linear-gradient(135deg, #722ed1, #9254de) !important;
    color: white !important;
}

.grid-action-icon {
    font-size: 18px !important;
}

.grid-action-text {
    font-size: 11px !important;
    font-weight: 500 !important;
    line-height: 1 !important;
}

/* Responsive Design */
@media (max-width: 1200px) {
    .performance-panel-container {
        width: 280px;
    }

    .depth-panel-container {
        width: 240px;
    }

    .selected-item-panel {
        width: 280px;
    }

    .action-panel-container {
        width: 280px;
    }
}

@media (max-width: 768px) {
    .performance-panel-container {
        position: relative;
        left: auto;
        top: auto;
        width: 100%;
        margin: 20px;
    }

    .depth-panel-container {
        position: relative;
        right: auto;
        top: auto;
        width: 100%;
        margin: 20px;
    }

    .selected-item-panel {
        position: relative;
        left: auto;
        bottom: auto;
        width: 100%;
        margin: 20px;
        transform: none;
    }

    .action-panel-container {
        position: relative;
        left: auto;
        bottom: auto;
        width: 100%;
        margin: 20px;
    }

    .action-buttons-grid {
        grid-template-columns: 1fr;
        gap: 8px;
    }

    .grid-action-button {
        height: 40px !important;
        width: 100% !important;
        flex-direction: row !important;
        gap: 8px !important;
    }

    .grid-action-icon {
        font-size: 16px !important;
    }

    .grid-action-text {
        font-size: 12px !important;
    }
}

/* Dark mode support */
@media (prefers-color-scheme: dark) {
    .app-background {
        background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
    }

    .modern-modal :deep(.ant-modal-content),
    .chart-container,
    .selected-item-card,
    .performance-panel,
    .depth-panel,
    .action-panel {
        background: rgba(30, 30, 30, 0.9);
        border-color: rgba(255, 255, 255, 0.08);
    }

    .chart-container {
        background: rgba(30, 30, 30, 0.1);
    }

    .modal-title,
    .selected-item-title,
    .panel-title {
        color: #ffffff;
    }

    .modal-subtitle,
    .selected-item-type,
    .progress-label,
    .metric-label,
    .detail-label,
    .depth-label,
    .config-label {
        color: #cccccc;
    }

    .modern-input {
        background: rgba(40, 40, 40, 0.8) !important;
        color: #ffffff !important;
        border-color: rgba(24, 144, 255, 0.3) !important;
    }

    .suggestions-container {
        background: rgba(40, 40, 40, 0.6);
    }

    .suggestion-text {
        color: #cccccc;
    }

    .metric-card {
        background: rgba(40, 40, 40, 0.6);
    }

    .metric-card:hover {
        background: rgba(40, 40, 40, 0.8);
    }

    .expand-hint {
        background: rgba(24, 144, 255, 0.1);
        color: #cccccc;
    }

    .grid-action-text {
        color: #ffffff !important;
    }
}
</style>
